using System;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;

using CStock;
using CUtil;


namespace CTrading
{
	/// <summary>
	/// Summary description for DialogIndicatorOnChartControl omposed.
	/// </summary>
	public class DialogIndicatorBuilder : System.Windows.Forms.Form
    {
		
		private string indicatorFormula;


		private System.Collections.ArrayList indicatorConditions;
		private System.Collections.ArrayList indicatorElementConditionsUserControls;
        private IIndicatorComposed indicatorComposed;

		private IProgramContext programContext;
		private EForms.EButton buttonCancel;
		private EForms.EButton buttonOK;
		private CTrading.CaptionIndicatorBuilder indicatorElementCaptions;
		private System.Windows.Forms.TextBox textBoxFormula;
        private System.Windows.Forms.Button buttonBuildFormula;
        private MenuStrip menuStrip1;
        private ToolStripMenuItem menuBase;
        private ToolStripMenuItem menuCreateNew;
        private ToolStripMenuItem openFromFile;
        private ToolStripMenuItem menuSave;
        private ToolStripMenuItem menuSaveAs;
        private ToolStripMenuItem menuAddElement;
        private ToolStripMenuItem menuRemoveElementLast;
        private ToolStripComboBox comboGlobalType;
        private IContainer components = null;

		public DialogIndicatorBuilder(IProgramContext myProgramContext)
		{
			this.programContext = myProgramContext;
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
		
			indicatorConditions = new System.Collections.ArrayList();
			indicatorElementConditionsUserControls = new System.Collections.ArrayList();
			if(myProgramContext.IndicatorComposed != null)
			{
				this.indicatorComposed = myProgramContext.IndicatorComposed; 
			}
			else
			{
				this.indicatorComposed = new IndicatorComposed();
				myProgramContext.IndicatorComposed = this.indicatorComposed;
			}
			this.Text = "New Indicator name: " + indicatorComposed.Name;

		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
				if(indicatorElementConditionsUserControls != null && indicatorElementConditionsUserControls.Count >0)
				{
					foreach(ConditionIndicatorBuilder tcc in indicatorElementConditionsUserControls)
					{
						tcc.ConditionChanged -= new ConditionChangedEventHandler(ConditionIndicatorBuilderChanded);
					
					}
					//ConditionIndicatorBuildersUserControl tcc = indicatorElementConditionsUserControls[i] as ConditionIndicatorBuildersUserControl ;

				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.buttonCancel = new EForms.EButton();
            this.buttonOK = new EForms.EButton();
            this.textBoxFormula = new System.Windows.Forms.TextBox();
            this.buttonBuildFormula = new System.Windows.Forms.Button();
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.menuBase = new System.Windows.Forms.ToolStripMenuItem();
            this.menuCreateNew = new System.Windows.Forms.ToolStripMenuItem();
            this.openFromFile = new System.Windows.Forms.ToolStripMenuItem();
            this.menuSave = new System.Windows.Forms.ToolStripMenuItem();
            this.menuSaveAs = new System.Windows.Forms.ToolStripMenuItem();
            this.menuAddElement = new System.Windows.Forms.ToolStripMenuItem();
            this.menuRemoveElementLast = new System.Windows.Forms.ToolStripMenuItem();
            this.comboGlobalType = new System.Windows.Forms.ToolStripComboBox();
            this.indicatorElementCaptions = new CTrading.CaptionIndicatorBuilder();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // buttonCancel
            // 
            this.buttonCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.buttonCancel.Font = new System.Drawing.Font("Verdana", 9F);
            this.buttonCancel.Location = new System.Drawing.Point(480, 368);
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new System.Drawing.Size(128, 24);
            this.buttonCancel.TabIndex = 4;
            this.buttonCancel.Text = "Cancel";
            this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
            // 
            // buttonOK
            // 
            this.buttonOK.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.buttonOK.Font = new System.Drawing.Font("Verdana", 9F);
            this.buttonOK.Location = new System.Drawing.Point(240, 368);
            this.buttonOK.Name = "buttonOK";
            this.buttonOK.Size = new System.Drawing.Size(104, 24);
            this.buttonOK.TabIndex = 3;
            this.buttonOK.Text = "OK";
            this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
            // 
            // textBoxFormula
            // 
            this.textBoxFormula.Location = new System.Drawing.Point(80, 304);
            this.textBoxFormula.Multiline = true;
            this.textBoxFormula.Name = "textBoxFormula";
            this.textBoxFormula.Size = new System.Drawing.Size(792, 48);
            this.textBoxFormula.TabIndex = 5;
            // 
            // buttonBuildFormula
            // 
            this.buttonBuildFormula.Location = new System.Drawing.Point(72, 368);
            this.buttonBuildFormula.Name = "buttonBuildFormula";
            this.buttonBuildFormula.Size = new System.Drawing.Size(112, 32);
            this.buttonBuildFormula.TabIndex = 6;
            this.buttonBuildFormula.Text = "Check Formula";
            this.buttonBuildFormula.Click += new System.EventHandler(this.buttonBuildFormula_Click);
            // 
            // menuStrip1
            // 
            this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None;
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.menuBase,
            this.comboGlobalType});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(193, 25);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // menuBase
            // 
            this.menuBase.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.menuCreateNew,
            this.openFromFile,
            this.menuSave,
            this.menuSaveAs,
            this.menuAddElement,
            this.menuRemoveElementLast});
            this.menuBase.Name = "menuBase";
            this.menuBase.Size = new System.Drawing.Size(62, 21);
            this.menuBase.Text = "Indicator";
            // 
            // menuCreateNew
            // 
            this.menuCreateNew.Name = "menuCreateNew";
            this.menuCreateNew.Size = new System.Drawing.Size(174, 22);
            this.menuCreateNew.Text = "Create New";
            this.menuCreateNew.Click += new System.EventHandler(this.menuCreateNew_Click);
            // 
            // openFromFile
            // 
            this.openFromFile.Name = "openFromFile";
            this.openFromFile.Size = new System.Drawing.Size(174, 22);
            this.openFromFile.Text = "Open From File";
            this.openFromFile.Click += new System.EventHandler(this.openFromFile_Click);
            // 
            // menuSave
            // 
            this.menuSave.Name = "menuSave";
            this.menuSave.Size = new System.Drawing.Size(174, 22);
            this.menuSave.Text = "Save";
            this.menuSave.Click += new System.EventHandler(this.menuSave_Click_1);
            // 
            // menuSaveAs
            // 
            this.menuSaveAs.Name = "menuSaveAs";
            this.menuSaveAs.Size = new System.Drawing.Size(174, 22);
            this.menuSaveAs.Text = "Save As ...";
            this.menuSaveAs.Click += new System.EventHandler(this.menuSaveAs_Click_1);
            // 
            // menuAddElement
            // 
            this.menuAddElement.Name = "menuAddElement";
            this.menuAddElement.Size = new System.Drawing.Size(174, 22);
            this.menuAddElement.Text = "Add Element";
            this.menuAddElement.Click += new System.EventHandler(this.menuAddElement_Click);
            // 
            // menuRemoveElementLast
            // 
            this.menuRemoveElementLast.Name = "menuRemoveElementLast";
            this.menuRemoveElementLast.Size = new System.Drawing.Size(174, 22);
            this.menuRemoveElementLast.Text = "Remove last element";
            this.menuRemoveElementLast.Click += new System.EventHandler(this.menuRemoveElementLast_Click);
            // 
            // comboGlobalType
            // 
            this.comboGlobalType.Items.AddRange(new object[] {
            "ShareType",
            "Global"});
            this.comboGlobalType.Name = "comboGlobalType";
            this.comboGlobalType.Size = new System.Drawing.Size(121, 21);
            this.comboGlobalType.Text = "ShareType";
            this.comboGlobalType.Click += new System.EventHandler(this.comboGlobalType_Click);
            // 
            // indicatorElementCaptions
            // 
            this.indicatorElementCaptions.Location = new System.Drawing.Point(0, 12);
            this.indicatorElementCaptions.Name = "indicatorElementCaptions";
            this.indicatorElementCaptions.Size = new System.Drawing.Size(1008, 40);
            this.indicatorElementCaptions.TabIndex = 0;
            // 
            // DialogIndicatorBuilder
            // 
            this.AcceptButton = this.buttonOK;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.CancelButton = this.buttonCancel;
            this.ClientSize = new System.Drawing.Size(1008, 425);
            this.Controls.Add(this.menuStrip1);
            this.Controls.Add(this.buttonBuildFormula);
            this.Controls.Add(this.textBoxFormula);
            this.Controls.Add(this.buttonCancel);
            this.Controls.Add(this.buttonOK);
            this.Controls.Add(this.indicatorElementCaptions);
            this.Name = "DialogIndicatorBuilder";
            this.Text = "DialogIndicatorBuilder";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

		}
		#endregion


		/// <summary>
		/// here I supply the method for changing the indicatorElement conditions
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void ConditionIndicatorBuilderChanded( object sender , ConditionChangedEvent e )
		{
			int i = e.Index;
			EvaluateFormula();


		}
		private void EvaluateFormula()
		{
			CreateIndicatorComposedFromUserControls();
			this.textBoxFormula.Text = this.indicatorFormula;
		}
		
		private void CreateDefaultIndicatorComposed()
		{
			RemoveAllConditionIndicatorBuilders();

			this.Cursor = System.Windows.Forms.Cursors.WaitCursor;

			indicatorComposed = new IndicatorComposed();
			object o = new Object();
			
			this.Cursor = System.Windows.Forms.Cursors.Default;
			this.Text = "New Indicator name: " + indicatorComposed.Name;

		}

	
	
	
		private void AddConditionFromElement(IndicatorElement MyindicatorElementCon)
		{
			ConditionIndicatorBuilder Mytcc = null;
			
			if(indicatorElementConditionsUserControls.Count < 1)
			{
				Mytcc = new ConditionIndicatorBuilder(0,MyindicatorElementCon);
				Mytcc.Left = this.ClientRectangle.Left +10;
				Mytcc.Top = this.ClientRectangle.Top +50;
			}
			else
			{
				Mytcc = new ConditionIndicatorBuilder(indicatorElementConditionsUserControls.Count,MyindicatorElementCon);
				ConditionIndicatorBuilder tccPrevious = indicatorElementConditionsUserControls[indicatorElementConditionsUserControls.Count -1] as ConditionIndicatorBuilder;
				
				Mytcc.Left = tccPrevious.Left ;
				Mytcc.Top = tccPrevious.Top +25;


			}

			Mytcc.ConditionChanged += new ConditionChangedEventHandler(ConditionIndicatorBuilderChanded);
			indicatorElementConditionsUserControls.Add(Mytcc);
			this.Controls.Add(Mytcc);

		}
		private bool CreateIndicatorComposedFromUserControls()
		{
			indicatorComposed.IndicatorElements = new List<IndicatorElement>();
			indicatorFormula = string.Empty;

            if (comboGlobalType.SelectedItem.ToString() == "Global")
            {
                indicatorComposed.IsGlobal = true;
            }
            else
            {
                indicatorComposed.IsGlobal = false;
            }
            indicatorFormula = string.Empty;

            
			foreach(Control c in this.Controls)
			{
				ConditionIndicatorBuilder cc = c as ConditionIndicatorBuilder ;
							
				if(cc != null)
				{
				
                    //gets all data out of the current selection !!
					IndicatorElement ie = cc.IndicatorElement;
                    indicatorComposed.IndicatorElements.Add(ie);
					
					string strValue = BuildFormulaFromElement(ie);
					indicatorFormula += strValue;
				}

			}
			return true;

		}
		private string BuildFormulaFromElement(IndicatorElement element)
		{
			string strVal = "  " ;
			
			strVal += element.OperatorString;
			
			if (element.Factor != 1F)
			{
				strVal += element.Factor.ToString();
				strVal += " " ;
				strVal +=element.OperatorFactorString;
			}

			if (element.IndicatorFunction != null && element.IndicatorFunction != string.Empty)
			{
				strVal += element.IndicatorFunction;
				strVal += element.IndicatorFunctionInterval.ToString();
				strVal += "(" ;
			}

            if (element.IndicatorOrShare != null && element.IndicatorOrShare != string.Empty)
			{
                strVal += element.IndicatorOrShare;
				strVal += element.IndicatorInterval.ToString();
			}
			if (element.IndicatorFunction != null && element.IndicatorFunction != string.Empty)
			{
				
				strVal += ")" ;

			}
			return strVal;
			
		}
		private void ShowAllConditionControls()
		{
            try
            {
                indicatorConditions = new System.Collections.ArrayList();
                indicatorElementConditionsUserControls = new System.Collections.ArrayList();

                for (int i = 0; i < this.indicatorComposed.IndicatorElements.Count; i++)
                {
                    IndicatorElement MyindicatorElementCon = this.indicatorComposed.IndicatorElements[i] as IndicatorElement;
                    AddConditionFromElement(MyindicatorElementCon);
                }
            }
            catch 
            {
                System.Windows.Forms.MessageBox.Show("Invalid file - does not contain a custom indicator "); 
            }
			

		}
		private bool SaveIndicatorComposed()
		{
			if(CreateIndicatorComposedFromUserControls())
			{
				if(indicatorComposed != null)
				{
					this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
					if(string.IsNullOrEmpty(indicatorComposed.Path ))
                        indicatorComposed.Path = ProgramContext.Instance.Configuration.Directories.ApplicationPath 
                            + ProgramContext.Instance.Configuration.Directories.IndicatorsComposedDir;
					indicatorComposed.Serialize();
					
					this.Cursor = System.Windows.Forms.Cursors.Default;
				}
				else
				{
					MessageBox.Show("No custom indicator specified");
				}
			
				this.Text = "Custom Indicator : " + indicatorComposed.Name;
                this.textBoxFormula.Text = this.indicatorFormula;
				return true;
			}
			else
			{
				System.Windows.Forms.MessageBox.Show("The indicator formula is not yet correct");
				return false;
			}
		}
	
		
		private void RemoveAllConditionIndicatorBuilders()
		{
			
			for(int i = this.Controls.Count -1; i > -1; i --)
			{
				ConditionIndicatorBuilder cc = this.Controls[i] as ConditionIndicatorBuilder;
				if(cc != null)
				{
					this.Controls.Remove(cc);
					cc.Dispose();
				}
				//cc = c as ConditionIndicatorBuilder;
			}
			
		}

		private void buttonOK_Click(object sender, System.EventArgs e)
		{
			if(SaveIndicatorComposed())
			{
				this.Close();
			}
		}

		private void buttonCancel_Click(object sender, System.EventArgs e)
		{
			this.Close();
		}

		private void buttonBuildFormula_Click(object sender, System.EventArgs e)
		{
			EvaluateFormula();
		}
		#region public properties

		public IIndicatorComposed IndicatorComposed 
		{
			get
			{
				return this.indicatorComposed;
			}
			set
			{
				this.indicatorComposed = value;
			}
			
		}
		public string IndicatorComposedName 
		{
			get
			{
				return this.indicatorComposed.FileName;
			}
			set
			{
				string fileName = value;
				System.IO.FileStream fstream =null;
				fstream = new System.IO.FileStream(fileName,System.IO.FileMode.Open,System.IO.FileAccess.ReadWrite);
				
				if(fstream != null)
				{
					//string strFileName = openFileDialog1.FileName;
					object o = new IndicatorComposed();		
					XMLSerializable.DeSerializeObject( ref o,fstream);
					indicatorComposed = o as IIndicatorComposed;

					fstream.Close();
					this.Text = "Custom Indicator : " + fileName;
					indicatorComposed.ID = CUtil.IOUtil.ExtractNameFromFileName(fileName);
					
				}
				ShowAllConditionControls();
			}
			
		}

		#endregion


        #region menu controls


      
      
     
        #endregion

      
        private void menuCreateNew_Click(object sender, EventArgs e)
        {
            CreateDefaultIndicatorComposed();
        }

        private void openFromFile_Click(object sender, EventArgs e)
        {
            RemoveAllConditionIndicatorBuilders();

            Stream myStream;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.InitialDirectory = this.programContext.Configuration.Directories.ApplicationPath +
                this.programContext.Configuration.Directories.IndicatorsComposedDir + "\\";
            openFileDialog1.Filter = "Custom Indicator System files (*.xml)|*.xml|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 1;
            openFileDialog1.RestoreDirectory = true;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {

                if ((myStream = openFileDialog1.OpenFile()) != null)
                {
                    //string strFileName = openFileDialog1.FileName;
                    object o = new IndicatorComposed();


                    XMLSerializable.DeSerializeObject(ref o, myStream);
                    indicatorComposed = o as IndicatorComposed;

                    myStream.Close();
                    this.Text = "Custom Indicator : " + openFileDialog1.FileName;

                    if (indicatorComposed != null)
                    {
                        if (indicatorComposed.IsGlobal)
                        {
                            this.comboGlobalType.SelectedIndex = 1;
                        }
                        ShowAllConditionControls();
                    }
                   
                }

            }

        }

        private void menuSave_Click_1(object sender, EventArgs e)
        {
            SaveIndicatorComposed();
        }

        private void menuSaveAs_Click_1(object sender, EventArgs e)
        {
            if (CreateIndicatorComposedFromUserControls())
            {
                if (indicatorComposed != null)
                {

                    Stream myStream;
                    SaveFileDialog saveFileDialog1 = new SaveFileDialog();

                    saveFileDialog1.InitialDirectory = this.programContext.Configuration.Directories.ApplicationPath +
                        this.programContext.Configuration.Directories.IndicatorsComposedDir;
                    saveFileDialog1.Filter = "Custom Indicator files (*.xml)|*.xml|All files (*.*)|*.*";
                    saveFileDialog1.FilterIndex = 1;
                    saveFileDialog1.RestoreDirectory = true;

                    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                    {


                        if ((myStream = saveFileDialog1.OpenFile()) != null)
                        {
                            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;

                            this.Text = "Custom Indicator : " + saveFileDialog1.FileName;
                            string[] arrStr = saveFileDialog1.FileName.Split(new Char[] { '\\' }, 100);
                            string strFileName = arrStr[arrStr.GetLength(0) - 1];
                            arrStr = strFileName.Split(new Char[] { '.' }, 100);

                            indicatorComposed.ID = arrStr[0];



                            XMLSerializable.SerializeObject(indicatorComposed, myStream);
                            this.Cursor = System.Windows.Forms.Cursors.Default;

                            myStream.Close();

                        }

                    }

                }
            }

        }

        private void menuAddElement_Click(object sender, EventArgs e)
        {
            if (indicatorComposed == null)
                indicatorComposed = new IndicatorComposed();
            IndicatorElement MyindicatorElement = new IndicatorElement();
            AddConditionFromElement(MyindicatorElement);

        }

        private void menuRemoveElementLast_Click(object sender, EventArgs e)
        {
            ConditionIndicatorBuilder cc = null;
            foreach (Control c in this.Controls)
            {
                cc = c as ConditionIndicatorBuilder;

            }
            if (cc != null)
            {
                this.Controls.Remove(cc);
            }
            EvaluateFormula();
        }

        private void comboGlobalType_Click(object sender, EventArgs e)
        {
            
        }

    }
}
